<?php
/**
 * @package     hubzero-cms
 * @author      Shawn Rice <zooley@purdue.edu>
 * @copyright   Copyright 2005-2011 Purdue University. All rights reserved.
 * @license     http://www.gnu.org/licenses/lgpl-3.0.html LGPLv3
 *
 * Copyright 2005-2011 Purdue University. All rights reserved.
 *
 * This file is part of: The HUBzero(R) Platform for Scientific Collaboration
 *
 * The HUBzero(R) Platform for Scientific Collaboration (HUBzero) is free
 * software: you can redistribute it and/or modify it under the terms of
 * the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any
 * later version.
 *
 * HUBzero is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * HUBzero is a registered trademark of Purdue University.
 */

// Check to ensure this file is included in Joomla!
defined('_JEXEC') or die('Restricted access');

ximport('Hubzero_Controller');


// Entry point for the component
class OaipmhController extends Hubzero_Controller {
	public function execute() {
		//error_reporting(0);

		//constants
		$maximum_records_per_request = 100;
		$repository_name = "Purdue Open Archive Initiative Repository";
		$hubname = "http://www.myhub.com";
		

		$this -> _task = JRequest::getVar('task', '');
		$this -> _id = JRequest::getInt('identifier', 0);
		$this -> _alias = JRequest::getVar('alias', '');
		$this -> _resid = JRequest::getInt('resid', 0);

		$operation = JRequest::getVar('verb', '');
		$identifier = JRequest::getVar('identifier', '');
		$metadataPrefix = JRequest::getVar('metadataPrefix', '');
		$from = JRequest::getVar('from', '');
		$until = JRequest::getVar('until', '');
		$set = JRequest::getVar('set', '');
		$resumption = JRequest::getVar('resumptionToken', '');

		if (($this -> _id || $this -> _alias) && !$this -> _task) {
			if ($this -> _resid && !$this -> _task) {
				$this -> _task = 'play';
			}
			$this -> _task = 'view';
		}

		//echo "verb:" . $operation . "<br>";
		//echo "identifier:" . $identifier . "<br>";
		//echo "metadataPrefix:" . $metadataPrefix . "<br>";

		$response = "";
		$response .= "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <OAI-PMH xmlns='http://www.openarchives.org/OAI/2.0/' 
         xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
         xsi:schemaLocation='http://www.openarchives.org/OAI/2.0/
         http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd'>";

		$date = date('c', time());

		$response .= "<responseDate>" . trim($date) . "</responseDate>";


		// The switch operation to decide on the verb
		switch($operation) {
			case 'GetRecord' :
				{
					$response .= "<request verb='GetRecord' identifier=\"" . $this -> _id . "\" metadataPrefix=\"$metadataPrefix\">http://www.myhub.com/com_resources</request>";

					$result = $this -> _getRecords($this -> _id);


					//error checking
					if (empty($metadataPrefix) || empty($identifier)) {
						$response .= "<error code=\"badArgument\"/>";
					} else if ($metadataPrefix != "oai_dc") {
						$response .= "<error code=\"cannotDisseminateFormat\"/>";
					}else if ($result == -1) {
						$response .= "<error code=\"idDoesNotExist\">No matching identifier in myhub</error>";
					} else {
						$response .= "<GetRecord>";
						$response .= $result;
						$response .= "</GetRecord>";
					}

				}
				break;
			case 'ListSets' :
				{
					$response .= "<request verb=\"ListSets\">http://www.myhub.com/com_resources</request>";

					if ($response == -1) {
						echo "error";
					}
					
					//error checking
					if (!empty($metadataPrefix) || !empty($identifier)) {
						$response .= "<error code=\"badArgument\"/>";
					} else if (!empty($resumption)) {
						$response .= "<error code=\"badResumptionToken\"/>";
					} else {
						$response .= "<ListSets>" . $this -> _getSets() . "</ListSets>";
					}

				}
				break;
			case 'Identify' :
				{
					$response .= "<request verb=\"Identify\">http://www.myhub.com/com_resources</request>";

					//error checking
					if (!empty($metadataPrefix) || !empty($identifier) || !empty($resumption)) {
					 $response .= "<error code=\"badArgument\"/>";
					 } else {
						$response .= " 
  					<Identify> 
    				<repositoryName>".$repository_name."</repositoryName> 
    				<baseURL>".$hubname."/oaipmh</baseURL>
				    <protocolVersion>2.0</protocolVersion> 
				    <adminEmail>nsomasun@purdue.edu</adminEmail> 
				    <earliestDatestamp>2011-08-01T12:00:00Z</earliestDatestamp> 
				    <deletedRecord>transient</deletedRecord> 
				    <granularity>YYYY-MM-DD</granularity> 
 					</Identify>";
					}

				}
				break;
			case 'ListMetadataFormats' :
				{
					$response .= "<request verb=\"ListMetadataFormats\"";

					$id = $this -> _id;
					if (!empty($id)) {
						$response .= " identifier=\"$this->_id\">";
					} else {
						$response .= ">";
					}

					$response .= "http://www.myhub.com/com_resources</request><ListMetadataFormats><metadataFormat><metadataPrefix>oai_dc</metadataPrefix><schema>http://www.openarchives.org/OAI/2.0/oai_dc.xsd</schema>
				     <metadataNamespace>http://www.openarchives.org/OAI/2.0/oai_dc/</metadataNamespace></metadataFormat></ListMetadataFormats>";
				}
				break;
			case 'ListIdentifiers' :
				{
					$database = &JFactory::getDBO();

					// Load the resource
					$resource = new ResourcesResource($database);
					$totalrecords = $resource -> getAllRecords($from, $until, $set);
					$response .= "<request verb='ListIdentifiers'  metadataPrefix=\"oai_dc\">http://www.myhub.com/com_resources</request>";

					$session = JFactory::getSession();
					$sessionTokenResumptionTemp = $session -> get($resumption);


					//error checking
					
					if ((!empty($from) && !($this -> _date_is_valid($from))) || (!empty($until) && !($this -> _date_is_valid($until)))) {
						$response .= "<error code=\"badArgument\"/>";
					} else if ((!empty($resumption) && empty($sessionTokenResumptionTemp))) {
						$response .= "<error code=\"badResumptionToken\"/>";

					} else if ($metadataPrefix != "oai_dc") {
						$response .= "<error code=\"cannotDisseminateFormat\"/>";
					}else if (count($totalrecords) == 0 || $totalrecords == -1 || empty($totalrecords)) {
						$response .= "<error code=\"noRecordsMatch\"/>";

					} else {
						$response .= "<request verb='ListRecords' identifier=\"" . $this -> _id . "\" metadataPrefix=\"oai_dc\">http://www.myhub.com/com_resources</request>";

						$database = &JFactory::getDBO();
						// Load the resource
						$resource = new ResourcesResource($database);
						$totalrecords = $resource -> getAllRecords($from, $until, $set);

						$session = &JFactory::getSession();
						$sessionTokenResumptionTemp = $session -> get($resumption);

						if ((!empty($from) && !($this -> _date_is_valid($from))) || (!empty($until) && !($this -> _date_is_valid($until)))) {
							$response .= "<error code=\"badArgument\"/>";
						} else if (!empty($resumption) && empty($sessionTokenResumptionTemp)) {
							$response .= "<error code=\"badResumptionToken\"/>";

						} else if ($metadataPrefix != "oai_dc") {
							$response .= "<error code=\"cannotDisseminateFormat\"/>";
						} else if (count($totalrecords) == 0 || $totalrecords == -1 || empty($totalrecords)) {
							$response .= "<error code=\"noRecordsMatch\"/>";

						} else {

							$result = "<ListIdentifiers>";
							$errorTemp = false;

							$begin = 0;
							$numberOfRecordsToWrite = 0;
							$completed = 0;
							$resumptionToken = 0;



							//check for the session resumption token existence
							if (!empty($resumption)) {

								$session = &JFactory::getSession();
								$completed = $session -> get($resumption);
								if (!isset($completed)) {
									$resultTemp = "error";
									$result = "<error code=\"badResumptionToken\"/>";
									$errorTemp = true;
									break;
								}
								$resumptionToken = $resumption;
							}

							if (count($totalrecords) - $completed <= 0) {
								$resultTemp = "error";
								$result = "<error code=\"noRecordsMatch\"/>";
								$errorTemp = true;

							}

							$split = false;
							
							//make sure you only write the flow control variable
							if ((count($totalrecords) - $completed) > $maximum_records_per_request) {
								$numberOfRecordsToWrite = $maximum_records_per_request;
								$begin = $completed;
								$split = true;
							} else {
								$numberOfRecordsToWrite = count($totalrecords) - $completed;
								$begin = $completed;
							}

							if (empty($resumption)) {
								$session = &JFactory::getSession();
								$resumptionToken = uniqid();
							}

							$session -> set($resumptionToken, $begin + $numberOfRecordsToWrite);

							for ($i = $begin; $i < ($begin + $numberOfRecordsToWrite); $i++) {

								$id = $totalrecords[$i] -> id;

								$resultTemp = $this -> _getHeader($id);
								if (($resultTemp == -1 && count($totalrecords) == 1) || ($resultTemp == -1 && (count($totalrecords) - $completed) == 1)) {
									$resultTemp = "error";
									$result = "<error code=\"noRecordsMatch\"/>";
									$errorTemp = true;
									break;
								} else if ($resultTemp != -1) {
									$result .= $resultTemp;
								}
							}

							if ($split) {
								$result .= "<resumptionToken completeListSize=\"" . $resumptionToken . "\" cursor=\"" . $begin . "\">" . $resumptionToken . "</resumptionToken>";
							}

							if (!$errorTemp)
								$result .= "</ListIdentifiers>";

							$response .= $result;

						}

					}

				}
				break;
			case 'ListRecords' :
				{

					$response .= "<request verb='ListRecords' identifier=\"" . $this -> _id . "\" metadataPrefix=\"oai_dc\">http://www.myhub.com/com_resources</request>";

					$database = &JFactory::getDBO();
					// Load the resource
					$resource = new ResourcesResource($database);
					$totalrecords = $resource -> getAllRecords($from, $until, $set);

					$session = &JFactory::getSession();
					$sessionTokenResumptionTemp = $session -> get($resumption);

					if ((!empty($from) && !($this -> _date_is_valid($from))) || (!empty($until) && !($this -> _date_is_valid($until)))) {
						$response .= "<error code=\"badArgument\"/>";
					} else if (!empty($resumption) && empty($sessionTokenResumptionTemp)) {
						$response .= "<error code=\"badResumptionToken\"/>";

					} else if ($metadataPrefix != "oai_dc") {
						$response .= "<error code=\"cannotDisseminateFormat\"/>";
					} else if (count($totalrecords) == 0 || $totalrecords == -1 || empty($totalrecords)) {
						$response .= "<error code=\"noRecordsMatch\"/>";

					} else {

						$result = "<ListRecords>";
						$errorTemp = false;

						$begin = 0;
						$numberOfRecordsToWrite = 0;
						$completed = 0;
						$resumptionToken = 0;

						if (!empty($resumption)) {

							$session = &JFactory::getSession();
							$completed = $session -> get($resumption);
							if (!isset($completed)) {
								$resultTemp = "error";
								$result = "<error code=\"badResumptionToken\"/>";
								$errorTemp = true;
								break;
							}
							$resumptionToken = $resumption;
						}

						if (count($totalrecords) - $completed <= 0) {
							$resultTemp = "error";
							$result = "<error code=\"noRecordsMatch\"/>";
							$errorTemp = true;

						}

						$split = false;
						if ((count($totalrecords) - $completed) > $maximum_records_per_request) {
							$numberOfRecordsToWrite = $maximum_records_per_request;
							$begin = $completed;
							$split = true;
						} else {
							$numberOfRecordsToWrite = count($totalrecords) - $completed;
							$begin = $completed;
						}

						if (empty($resumption)) {
							$session = &JFactory::getSession();
							$resumptionToken = uniqid();
						}

						$session -> set($resumptionToken, $begin + $numberOfRecordsToWrite);

						for ($i = $begin; $i < ($begin + $numberOfRecordsToWrite); $i++) {

							$id = $totalrecords[$i] -> id;

							$resultTemp = $this -> _getRecords($id);
							if (($resultTemp == -1 && count($totalrecords) == 1) || ($resultTemp == -1 && (count($totalrecords) - $completed) == 1)) {
								$resultTemp = "error";
								$result = "<error code=\"noRecordsMatch\"/>";
								$errorTemp = true;
								break;
							} else if ($resultTemp != -1) {
								$result .= $resultTemp;
							}
						}

						if ($split) {
							$result .= "<resumptionToken completeListSize=\"" . $resumptionToken . "\" cursor=\"" . $begin . "\">" . $resumptionToken . "</resumptionToken>";
						}

						if (!$errorTemp)
							$result .= "</ListRecords>";

						$response .= $result;

					}

				}
				break;
			default :
				{
					$response .= "<request>http://www.myhub.com/com_resources</request><error code=\"badVerb\">Illegal OAI verb</error>";
				}
				break;
		}
		$response .= "</OAI-PMH>";

		$response = $this -> formatXmlString1($response);
		echo $response;

		exit ;
		return;
	}

	function _date_is_valid($str) {
		list($y, $m, $d) = explode('-', $str);
		return checkdate($m, $d, $y);
	}

	function formatXmlString1($xml) {

		// add marker linefeeds to aid the pretty-tokeniser (adds a linefeed between all tag-end boundaries)
		$xml = preg_replace('/(>)(<)(\/*)/', "$1\n$2$3", $xml);

		// now indent the tags
		$token = strtok($xml, "\n");
		$result = '';
		// holds formatted version as it is built
		$pad = 0;
		// initial indent
		$matches = array();
		// returns from preg_matches()

		// scan each line and adjust indent based on opening/closing tags
		while ($token !== false) :

			// test for the various tag states

			// 1. open and closing tags on same line - no change
			if (preg_match('/.+<\/\w[^>]*>$/', $token, $matches)) :
				$indent = 0;
			// 2. closing tag - outdent now
			elseif (preg_match('/^<\/\w/', $token, $matches)) :
				$pad--;
			// 3. opening tag - don't pad this one, only subsequent tags
			elseif (preg_match('/^<\w[^>]*[^\/]>.*$/', $token, $matches)) :
				$indent = 1;
			// 4. no indentation needed
			else :
				$indent = 0;
			endif;

			// pad the line with the required number of leading spaces
			$line = str_pad($token, strlen($token) + $pad, ' ', STR_PAD_LEFT);
			$result .= $line . "\n";
			// add to the cumulative result, with linefeed
			$token = strtok("\n");
			// get the next token
			$pad += $indent;
			// update the pad size for subsequent lines
		endwhile;

		return $result;
	}

	function formatXmlString($xml) {

		// add marker linefeeds to aid the pretty-tokeniser (adds a linefeed between all tag-end boundaries)
		$xml = preg_replace('/(>)(<)(\/*)/', "$1\n$2$3", $xml);

		// now indent the tags
		$token = strtok($xml, "\n");
		$result = '';
		// holds formatted version as it is built
		$pad = 0;
		// initial indent
		$matches = array();
		// returns from preg_matches()

		// scan each line and adjust indent based on opening/closing tags
		while ($token !== false) :

			// test for the various tag states

			// 1. open and closing tags on same line - no change
			if (preg_match('/.+<\/\w[^>]*>$/', $token, $matches)) :
				$indent = 0;
			// 2. closing tag - outdent now
			elseif (preg_match('/^<\/\w/', $token, $matches)) :
				$pad--;
			// 3. opening tag - don't pad this one, only subsequent tags
			elseif (preg_match('/^<\w[^>]*[^\/]>.*$/', $token, $matches)) :
				$indent = 1;
			// 4. no indentation needed
			else :
				$indent = 0;
			endif;

			// pad the line with the required number of leading spaces
			$line = str_pad($token, strlen($token) + $pad, ' ', STR_PAD_LEFT);
			$result .= $line . "\n";
			// add to the cumulative result, with linefeed
			$token = strtok("\n");
			// get the next token
			$pad += $indent;
			// update the pad size for subsequent lines
		endwhile;

		return $result;
	}

	protected function _getSets() {

		$sets = "";

		$database = &JFactory::getDBO();

		// Get major types
		$t = new ResourcesType($database);
		$types = $t -> getMajorTypes();

		if (empty($types)) {
			echo "Empty array";
			return;
		}

		for ($i = 0; $i < count($types); $i++) {
			$spectrimmed = str_replace(" ", "", $types[$i] -> type);

			$sets .= "<set><setSpec>" . $spectrimmed . "</setSpec>";
			$sets .= "<setName>" . ($types[$i] -> type) . "</setName>";
			$sets .= "<setDescription> <oai_dc:dc 
          xmlns:oai_dc=\"http://www.openarchives.org/OAI/2.0/oai_dc/\" 
          xmlns:dc=\"http://purl.org/dc/elements/1.1/\" 
          xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" 
          xsi:schemaLocation=\"http://www.openarchives.org/OAI/2.0/oai_dc/ 
          http://www.openarchives.org/OAI/2.0/oai_dc.xsd\"><dc:description>" . ($types[$i] -> description) . "</dc:description>
       </oai_dc:dc></setDescription></set>";

		}

		return $sets;
	}

	//-----------


	//get the record with id $id
	protected function _getRecords($id) {


		// Rsource ID (primary method of identifying a resource)
		$alias = JRequest::getVar('alias', '');
		// Alternate method of identifying a resource
		$fsize = JRequest::getVar('fsize', '');
		// A parameter to see file size without formatting
		$revision = JRequest::getVar('rev', '');
		// Get svk revision of a tool
		$tab = JRequest::getVar('active', 'about');
		// The active tab (section)

		// Ensure we have an ID or alias to work with
		if (!$id && !$alias) {
			$this -> _redirect = JRoute::_('index.php?option=' . $this -> _option);
			return -1;
		}



		$database = &JFactory::getDBO();

		// Load the resource
		$resource = new ResourcesResource($database);
		if ($alias) {
			$alias = str_replace(':', '-', $alias);
			$resource -> loadAlias($alias);
			$id = $resource -> id;
		} else {
			$resource -> load($id);
			$alias = $resource -> alias;
		}
		
		

		// Make sure we got a result from the database
		if (!$resource || !$resource -> title) {
			//JError::raiseError(404, JText::_('COM_RESOURCES_RESOURCE_NOT_FOUND'));
			return -1;
		}

		// Make sure the resource is published and standalone
		if ($resource -> published == 0 || $resource -> standalone != 1) {
			//JError::raiseError(403, JText::_('ALERTNOTAUTH'));
			return -1;
		}

		// Initiate a resource helper class
		$helper = new ResourcesHelper($resource -> id, $database);

		// Is the visitor authorized to edit this resource?
		$helper -> getContributorIDs();
		$authorized = $this -> _authorize($helper -> contributorIDs);

		// Make sure they have access to view this resource
		if ($resource -> access == 4) {
			if ($this -> checkGroupAccess($resource) && !$authorized) {
				//JError::raiseError(403, JText::_('ALERTNOTAUTH'));
				return -1;
			}
		}

		// Build the pathway
		$normalized_valid_chars = 'a-zA-Z0-9';
		$typenorm = preg_replace("/[^$normalized_valid_chars]/", "", $resource -> getTypeTitle());
		$typenorm = strtolower($typenorm);

		$app = &JFactory::getApplication();
		if ($resource -> group_owner) {
			// Alter the pathway to reflect a group owned resource
			ximport('Hubzero_Group');
			$group = Hubzero_Group::getInstance($resource -> group_owner);

			$pathway = &$app -> getPathway();
			$pathway -> _pathway = array();
			$pathway -> _count = 0;

			$pathway -> addItem('Groups', JRoute::_('index.php?option=com_groups'));
			$pathway -> addItem(stripslashes($group -> get('description')), JRoute::_('index.php?option=com_groups&gid=' . $resource -> group_owner));
			$pathway -> addItem('Resources', JRoute::_('index.php?option=com_groups&gid=' . $resource -> group_owner . '&active=resources'));
			$pathway -> addItem($resource -> getTypeTitle(), JRoute::_('index.php?option=com_groups&gid=' . $resource -> group_owner . '&active=resources&area=' . $typenorm));
		} else {
			$pathway = &$app -> getPathway();
			$pathway -> addItem($resource -> getTypeTitle(), JRoute::_('index.php?option=' . $this -> _option . '&type=' . $typenorm));
		}

		// Tool development version requested
		$juser = &JFactory::getUser();
		if ($juser -> get('guest') && $revision == 'dev') {
			//JError::raiseError(403, JText::_('ALERTNOTAUTH'));
			return -1;
		}

		if (($revision == 'dev' && $alias) or (!$revision && $resource -> type == 7 && $resource -> published != 1)) {
			$objT = new Tool($database);
			$toolid = $objT -> getToolId($alias);
			if (!$this -> check_toolaccess($toolid)) {
				//JError::raiseError(403, JText::_('ALERTNOTAUTH'));
				return -1;
			}
		}

		// Whew! Finally passed all the checks
		// Let's get down to business...
		$this -> resource = $resource;

		// Push some styles to the template
		$this -> _getStyles();

		// Push some scripts to the template
		$this -> _getScripts();

		// Version checks (tools only)
		$alltools = array();
		$thistool = '';
		$curtool = '';

		if ($resource -> type == 7 && $resource -> alias) {
			$tables = $database -> getTableList();
			$table = $database -> _table_prefix . 'tool_version';

			// Get contribtool params
			$tparams = &JComponentHelper::getParams('com_contribtool');
			$ldap = $tparams -> get('ldap_read');

			if (in_array($table, $tables)) {
				$tv = new ToolVersion($database);
				$tv -> getToolVersions('', $alltools, $alias, $ldap);

				if ($alltools) {
					foreach ($alltools as $tool) {
						// Archive version, if requested
						if (($revision && $tool -> revision == $revision && $revision != 'dev') or ($revision == 'dev' and $tool -> state == 3)) {
							$thistool = $tool;
						}
						// Current version
						if ($tool -> state == 1 && count($alltools) > 1 && $alltools[1] -> version == $tool -> version) {
							$curtool = $tool;
						}
						// Dev version
						if (!$revision && count($alltools) == 1 && $tool -> state == 3) {
							$thistool = $tool;
							$revision = 'dev';
						}
					}

					if (!$thistool && !$curtool && count($alltools) > 1) {
						// Tool is retired, display latest unpublished version
						$thistool = $alltools[1];
						$revision = $alltools[1] -> revision;
					}

					if ($curtool && $thistool && $thistool == $curtool) {
						// Display default resource page for current version
						$thistool = '';
					}
				}

				// Replace resource info with requested version
				$tv -> compileResource($thistool, $curtool, &$resource, $revision, $tparams);
			}
		}

		// Record the hit
		$resource -> hit($id);
		//echo "-->".print_r($resource)."<--";

		$db = &JFactory::getDBO();
		$t = new ResourcesType($db);
		$types = $t -> getMajorTypes();
	

		$resource -> _type = new ResourcesType($database);
		$resource -> _type -> load($resource -> type);
		$resource -> _type -> _params = new JParameter($resource -> _type -> params);
		
			

		
		$towrite = "<record><header>";

		$towrite .= "<identifier>" . $id . "</identifier>\n";

		$datestamp = strtotime($resource -> created);
		$datestamp = date("Y-m-d", $datestamp);

		$towrite .= "<datestamp>" . $datestamp . "</datestamp>\n";

		$towrite .= "<setSpec>" . $resource -> _type -> type . "</setSpec>\n";
		$towrite .= "</header>";

		$towrite .= "<metadata><oai_dc:dc 
         xmlns:oai_dc='http://www.openarchives.org/OAI/2.0/oai_dc/' 
         xmlns:dc= 'http://purl.org/dc/elements/1.1/'
         xmlns:xsi= 'http://www.w3.org/2001/XMLSchema-instance' 
         xsi:schemaLocation='http://www.openarchives.org/OAI/2.0/oai_dc/ 
         http://www.openarchives.org/OAI/2.0/oai_dc.xsd'>";

		$towrite .=  $dc_title= "<dc:title>" . $resource -> title . "</dc:title>\n";
		//$towrite .= "<rating>" . $resource -> rating . "</rating>\n";
		$towrite .= $dc_date = "<dc:date>" . $resource -> created . "</dc:date>\n";

		//$towrite .= "<hits>" . $resource -> hits . "</hits>\n";
		$towrite .= $dc_description = "<dc:description>" . strip_tags($resource -> introtext) . "</dc:description>\n";

		$towrite .= $dc_id = "<dc:identifier>" . $id . "</dc:identifier>\n";
		$helper -> getCons();
		$helper -> getContributors();
		$contrib = $helper -> contributors;
		$contrib = strip_tags($contrib);
		$towrite .= $dc_creator = "<dc:creator>" . $contrib . "</dc:creator>\n";

		// Initiate a resource helper class
		/*$helper = new ResourcesHelper( $resource->id, $database );

		 // Is the visitor authorized to edit this resource?
		 $helper->getContributorIDs();
		 $authorized = $this->_authorize( $helper->contributorIDs );*/

		// Do not show for tool versions
		if ($thistool && $revision != 'dev') {
			$authorized = false;
		}

		// Get Resources plugins
		JPluginHelper::importPlugin('resources');
		$dispatcher = &JDispatcher::getInstance();

		$sections = array();
		$cats = array();



		$towrite .= "<dc:type>" . $resource -> _type -> type . "</dc:type>";

		// We need to do this here because we need some stats info to pass to the body
		if (!$thistool) {
			// Trigger the functions that return the areas we'll be using
			$cats = $dispatcher -> trigger('onResourcesAreas', array($resource));

			// Get the sections
			$sections = $dispatcher -> trigger('onResources', array($resource, $this -> _option, array($tab), 'all'));
		}

		$available = array('play');
		foreach ($cats as $cat) {
			$name = key($cat);
			if ($name != '') {
				$available[] = $name;
			}
		}
		if ($tab != 'about' && !in_array($tab, $available)) {
			$tab = 'about';
		}

		// Get parameters and merge with the component params
		$rparams = &new JParameter($resource -> params);
		$params = $this -> config;
		$params -> merge($rparams);

		// Get attributes
		$attribs = &new JParameter($resource -> attribs);

		$juser = &JFactory::getUser();
		if (!$juser -> get('guest')) {
			ximport('Hubzero_User_Helper');
			$xgroups = Hubzero_User_Helper::getGroups($juser -> get('id'), 'all');
			// Get the groups the user has access to
			$usersgroups = $this -> getUsersGroups($xgroups);
		} else {
			$usersgroups = array();
		}

		$no_html = JRequest::getInt('no_html', 0);

		$body = '';
		// Build the HTML of the "about" tab
		if ($resource -> type == 7 && $resource -> alias && !$no_html && strtolower($tab) == 'about') {
			// Tool page view
			$body = ResourcesHtml::abouttool($database, $authorized, $usersgroups, $resource, $helper, $this -> config, $sections, $thistool, $curtool, $alltools, $resource -> revision, $params, $attribs, $this -> _option, $fsize);
			$towrite .= ResourcesHtml::abouttoolXml($database, $authorized, $usersgroups, $resource, $helper, $this -> config, $sections, $thistool, $curtool, $alltools, $resource -> revision, $params, $attribs, $this -> _option, $fsize);

		} else if (strtolower($tab) == 'about') {
			// Default view of about tab

			$body = ResourcesHtml::aboutnontool($database, $authorized, $usersgroups, $resource, $helper, $this -> config, $sections, $params, $attribs, $this -> _option, $fsize);
			$towrite .= ResourcesHtml::aboutnontoolXml($database, $authorized, $usersgroups, $resource, $helper, $this -> config, $sections, $params, $attribs, $this -> _option, $fsize);

		}
		$towrite .= "</oai_dc:dc>";

		$towrite .= "</metadata>";

		$towrite .= "</record>";

		return $towrite;
	}

	
	//Get the header about a particular resource
	protected function _getHeader($id) {

		// Rsource ID (primary method of identifying a resource)
		$alias = JRequest::getVar('alias', '');
		// Alternate method of identifying a resource
		$fsize = JRequest::getVar('fsize', '');
		// A parameter to see file size without formatting
		$revision = JRequest::getVar('rev', '');
		// Get svk revision of a tool
		$tab = JRequest::getVar('active', 'about');
		// The active tab (section)

		// Ensure we have an ID or alias to work with
		if (!$id && !$alias) {
			//$this -> _redirect = JRoute::_('index.php?option=' . $this -> _option);
			return -1;
		}

		$database = &JFactory::getDBO();

		// Load the resource
		$resource = new ResourcesResource($database);
		if ($alias) {
			$alias = str_replace(':', '-', $alias);
			$resource -> loadAlias($alias);
			$id = $resource -> id;
		} else {
			$resource -> load($id);
			$alias = $resource -> alias;
		}

		// Make sure we got a result from the database
		if (!$resource || !$resource -> title) {
			//JError::raiseError(404, JText::_('COM_RESOURCES_RESOURCE_NOT_FOUND'));
			return -1;
		}

		// Make sure the resource is published and standalone
		if ($resource -> published == 0 || $resource -> standalone != 1) {
			//JError::raiseError(403, JText::_('ALERTNOTAUTH'));
			return -1;
		}

		// Initiate a resource helper class
		$helper = new ResourcesHelper($resource -> id, $database);

		// Is the visitor authorized to edit this resource?
		$helper -> getContributorIDs();
		$authorized = $this -> _authorize($helper -> contributorIDs);

		// Make sure they have access to view this resource
		if ($resource -> access == 4) {
			if ($this -> checkGroupAccess($resource) && !$authorized) {
				//JError::raiseError(403, JText::_('ALERTNOTAUTH'));
				return -1;
			}
		}

		// Build the pathway
		$normalized_valid_chars = 'a-zA-Z0-9';
		$typenorm = preg_replace("/[^$normalized_valid_chars]/", "", $resource -> getTypeTitle());
		$typenorm = strtolower($typenorm);

		$app = &JFactory::getApplication();
		if ($resource -> group_owner) {
			// Alter the pathway to reflect a group owned resource
			ximport('Hubzero_Group');
			$group = Hubzero_Group::getInstance($resource -> group_owner);

			$pathway = &$app -> getPathway();
			$pathway -> _pathway = array();
			$pathway -> _count = 0;

			$pathway -> addItem('Groups', JRoute::_('index.php?option=com_groups'));
			$pathway -> addItem(stripslashes($group -> get('description')), JRoute::_('index.php?option=com_groups&gid=' . $resource -> group_owner));
			$pathway -> addItem('Resources', JRoute::_('index.php?option=com_groups&gid=' . $resource -> group_owner . '&active=resources'));
			$pathway -> addItem($resource -> getTypeTitle(), JRoute::_('index.php?option=com_groups&gid=' . $resource -> group_owner . '&active=resources&area=' . $typenorm));
		} else {
			$pathway = &$app -> getPathway();
			$pathway -> addItem($resource -> getTypeTitle(), JRoute::_('index.php?option=' . $this -> _option . '&type=' . $typenorm));
		}

		// Tool development version requested
		$juser = &JFactory::getUser();
		if ($juser -> get('guest') && $revision == 'dev') {
			//JError::raiseError(403, JText::_('ALERTNOTAUTH'));
			return -1;
		}

		if (($revision == 'dev' && $alias) or (!$revision && $resource -> type == 7 && $resource -> published != 1)) {
			$objT = new Tool($database);
			$toolid = $objT -> getToolId($alias);
			if (!$this -> check_toolaccess($toolid)) {
				//JError::raiseError(403, JText::_('ALERTNOTAUTH'));
				return -1;
			}
		}

		// Whew! Finally passed all the checks
		// Let's get down to business...
		$this -> resource = $resource;

		// Push some styles to the template
		$this -> _getStyles();

		// Push some scripts to the template
		$this -> _getScripts();

		// Version checks (tools only)
		$alltools = array();
		$thistool = '';
		$curtool = '';

		if ($resource -> type == 7 && $resource -> alias) {
			$tables = $database -> getTableList();
			$table = $database -> _table_prefix . 'tool_version';

			// Get contribtool params
			$tparams = &JComponentHelper::getParams('com_contribtool');
			$ldap = $tparams -> get('ldap_read');

			if (in_array($table, $tables)) {
				$tv = new ToolVersion($database);
				$tv -> getToolVersions('', $alltools, $alias, $ldap);

				if ($alltools) {
					foreach ($alltools as $tool) {
						// Archive version, if requested
						if (($revision && $tool -> revision == $revision && $revision != 'dev') or ($revision == 'dev' and $tool -> state == 3)) {
							$thistool = $tool;
						}
						// Current version
						if ($tool -> state == 1 && count($alltools) > 1 && $alltools[1] -> version == $tool -> version) {
							$curtool = $tool;
						}
						// Dev version
						if (!$revision && count($alltools) == 1 && $tool -> state == 3) {
							$thistool = $tool;
							$revision = 'dev';
						}
					}

					if (!$thistool && !$curtool && count($alltools) > 1) {
						// Tool is retired, display latest unpublished version
						$thistool = $alltools[1];
						$revision = $alltools[1] -> revision;
					}

					if ($curtool && $thistool && $thistool == $curtool) {
						// Display default resource page for current version
						$thistool = '';
					}
				}

				// Replace resource info with requested version
				$tv -> compileResource($thistool, $curtool, &$resource, $revision, $tparams);
			}
		}

		// Record the hit
		$resource -> hit($id);
		$rnumber = $resource -> type;

		$db = &JFactory::getDBO();
		$t = new ResourcesType($db);
		$types = $t -> getMajorTypes();



		$resource -> _type = new ResourcesType($database);
		$resource -> _type -> load($resource -> type);
		$resource -> _type -> _params = new JParameter($resource -> _type -> params);
		
		
		
		$towrite = "<header>";
		$towrite .= "<identifier>" . $id . "</identifier>\n";

		$datestamp = strtotime($resource -> created);
		$datestamp = date("Y-m-d", $datestamp);
		$towrite .= "<datestamp>" . $datestamp . "</datestamp>\n";
		$towrite .= "<setSpec>" . $resource -> _type -> type . "</setSpec>\n";
		$towrite .= "</header>";

		return $towrite;
	}

}
